package com.yy.xshell.loopPull;

import com.yy.xshell.core.SshCore;
import com.yy.xshell.auth.SessionContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.LockSupport;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @author wxy
 * @version 1.0
 * @date 2024/8/21 18:58
 */
public class LoopCore {

    private Logger log = LoggerFactory.getLogger(SshCore.class);

    private static final Map<String, SessionStream> list = new HashMap<>();

    private static final ReentrantLock lock = new ReentrantLock();

    private long sleep = 100L;

    private Thread thread = null;

    public void start(){
        thread = new Thread(){
            @Override
            public void run() {
                while (true){
                    if(list.size() == 0){
                        LockSupport.park();
                    }
                    lock.lock();
                    for(String key : list.keySet()){
                        try {
                            SessionStream sessionStream = list.get(key);
                            SessionContext.set(sessionStream.getSessionInfo());
                            if(sessionStream.getInputStream() == null || sessionStream.getInputStream().available() == -1){
                                if(sessionStream.getInputStream() != null){
                                    sessionStream.getInputStream().close();
                                }
                                list.remove(key);
                                break;
                            }else if(sessionStream.getInputStream().available() > 0){
                                sessionStream.sendMsg();
                            }
                        }catch (Exception e){
                            log.error("key{}", key,  e);
                        }finally {
                            SessionContext.clear();
                        }
                    }
                    lock.unlock();
                    try {
                        TimeUnit.MILLISECONDS.sleep(sleep);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        };
        thread.start();
    }

    public void add(SessionStream sessionStream){
        try {
            lock.lock();
            if(list.containsKey(sessionStream.toString())){
                SessionStream stream = list.get(sessionStream.toString());
                stream.getInputStream().close();
                stream.setInputStream(sessionStream.getInputStream());
                list.put(sessionStream.toString(), stream);
                return;
            }
            list.put(sessionStream.toString() ,sessionStream);
        }catch (Exception e){
            log.error("add", e);
        }finally {
            lock.unlock();
            if(thread != null){
                LockSupport.unpark(thread);
            }
        }
    }

    public SessionStream getAndRemove(String userId, String sessionKey){
        SessionStream sessionStream = null;
        try {
            lock.lock();
            for(String key : list.keySet()){
                SessionStream stream = list.get(key);
                if(stream.getUserId().equals(userId) && stream.getSessionKey().equals(sessionKey)){
                    sessionStream = stream;
                    list.remove(stream);
                }
            }
        }catch (Exception e){
            log.error("getAndRemove", e);
        }finally {
            lock.unlock();
        }
        return sessionStream;
    }

    public List<SessionStream> getAndRemoveByUserId(String userId){
        List<SessionStream> resultList = new LinkedList<>();
        try {
            lock.lock();
            for(String key : list.keySet()){
                SessionStream stream = list.get(key);
                if(stream.getUserId().equals(userId)){
                    resultList.add(stream);
                    list.remove(stream);
                }
            }
        }catch (Exception e){
            log.error("getAndRemoveByUserId", e);
        }finally {
            lock.unlock();
        }


        return resultList;
    }
}
